package com.portal.framework.util;

import java.util.Map;

import org.hibernate.EntityMode;
import org.hibernate.SessionFactory;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.persister.entity.AbstractEntityPersister;

/**
 * hibernate 辅助工具类
 * 
 * 
 * @author ¬˸��
 */
public class HibernateUtil {

	/**
	 * 根据映射类和属性名得到数据库的字段名
	 * 
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @param fieldName
	 *            属性名
	 * @return
	 */
	public static String[] getColumnNames(SessionFactory sessionFactory,
			Class<?> clazz, String fieldName) {
		AbstractEntityPersister ep = getEntityPersisterByClassName(
				sessionFactory, clazz);
		if (ep != null) {
			return ep.getPropertyColumnNames(fieldName);
		}
		return null;
	}

	/**
	 * 根据映射类和属性名得到数据库的字段名
	 * 
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @param fieldName
	 *            属性名
	 * @return
	 */
	public static String getColumnName(SessionFactory sessionFactory,
			Class<?> clazz, String fieldName) {
		String[] columnNames = getColumnNames(sessionFactory, clazz, fieldName);
		if (CollectionUtils.notEmpty(columnNames)) {
			return columnNames[0];
		}
		return null;
	}

	/**
	 * 根据映射类得到表名
	 * 
	 * 
	 * @param sessionFactory
	 * @param clazz
	 * @return
	 */
	public static String getTableName(SessionFactory sessionFactory,
			Class<?> clazz) {
		AbstractEntityPersister ep = getEntityPersisterByClassName(
				sessionFactory, clazz);
		if (ep != null) {
			ep.getTableName();
		}
		return null;
	}

	/**
	 * 得到主键名字段名
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @return 主键的字段名,如果为多个则表示为组合主键
	 * 
	 */
	public static String[] getPKColumnNames(SessionFactory sessionFactory,
			Class<?> clazz) {
		AbstractEntityPersister ep = getEntityPersisterByClassName(
				sessionFactory, clazz);
		if (ep != null) {
			ep.getKeyColumnNames();
		}

		return null;
	}

	/**
	 * 得到主键名字段名
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @return 主键的字段名
	 */
	public static String getPKColumnName(SessionFactory sessionFactory,
			Class<?> clazz) {
		String[] names = getPKColumnNames(sessionFactory, clazz);
		if (CollectionUtils.notEmpty(names)) {
			return names[0];
		}
		return null;
	}

	/**
	 * 得到主键的属性名
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @return
	 */
	public static String getPKFieldName(SessionFactory sessionFactory,
			Class<?> clazz) {
		AbstractEntityPersister ep = getEntityPersisterByClassName(
				sessionFactory, clazz);
		if (ep == null) {
			return null;
		}
		return ep.getIdentifierPropertyName();

	}

	/**
	 * 根据表名和字段名得到对方映射类中的属性名
	 * 
	 * @param sessionFactory
	 * @param tableName
	 *            表名
	 * @param columnName
	 *            字段名
	 * 
	 * @return 对应的属性名
	 */
	public static String getFieldName(SessionFactory sessionFactory,
			String tableName, String columnName) {
		if (columnName == null) {
			return null;
		}
		AbstractEntityPersister ep = getEntityPersisterByTableName(
				sessionFactory, tableName);
		if (ep != null) {
			String[] names = ep.getPropertyNames();
			for (String n : names) {
				String[] name = ep.getPropertyColumnNames(n);
				if (CollectionUtils.notEmpty(name)) {
					if (name[0].equalsIgnoreCase(columnName)) {
						return n;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 根据表名和字段名得到对方映射类中的属性名
	 * 
	 * @param sessionFactory
	 * @param clazz
	 *            映射类(DTO)
	 * @param columnName
	 *            字段名
	 * 
	 * @return 对应的属性名
	 */
	public static String getFieldName(SessionFactory sessionFactory,
			Class<?> clazz, String columnName) {
		AbstractEntityPersister ep = getEntityPersisterByClassName(
				sessionFactory, clazz);
		if (ep != null) {
			String[] names = ep.getPropertyNames();
			for (String n : names) {
				String[] name = ep.getPropertyColumnNames(n);
				if (CollectionUtils.notEmpty(name)) {
					if (name[0].equalsIgnoreCase(columnName)) {
						return n;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 根据表名得到映射类(DTO)
	 * 
	 * @param sessionFactory
	 * @param tableName
	 *            表名
	 * @return
	 */
	public static Class<?> getMappedClassByTableName(
			SessionFactory sessionFactory, String tableName) {
		AbstractEntityPersister ep = getEntityPersisterByTableName(
				sessionFactory, tableName);
		if (ep != null) {
			return ep.getMappedClass(EntityMode.POJO);
			// return ep.getName();
		}
		return null;
	}

	private static AbstractEntityPersister getEntityPersisterByClassName(
			SessionFactory sessionFactory, Class<?> clazz) {
		if (sessionFactory == null || clazz == null) {
			return null;
		}

		ClassMetadata meta = sessionFactory.getClassMetadata(clazz);
		if (meta == null) {
			return null;
		}
		if (meta instanceof AbstractEntityPersister) {
			return (AbstractEntityPersister) meta;
		}

		return null;

	}

	@SuppressWarnings("unchecked")
	private static AbstractEntityPersister getEntityPersisterByTableName(
			SessionFactory sessionFactory, String tableName) {
		if (sessionFactory == null || tableName == null) {
			return null;
		}
		Map<String, ClassMetadata> metas = sessionFactory.getAllClassMetadata();
		if (metas == null) {
			return null;
		}
		ClassMetadata meta = null;
		for (String key : metas.keySet()) {
			meta = metas.get(key);
			if (meta == null) {
				continue;
			}
			if (meta instanceof AbstractEntityPersister) {
				AbstractEntityPersister ep = (AbstractEntityPersister) meta;
				String tn = ep.getTableName();
				if(tn.equalsIgnoreCase(tableName)){
					return ep;
				}
			}
		}

		return null;
	}

}
